const Document = require('../models/Document');
const Card = require('../models/Card');
const DocumentParser = require('../services/documentParser');
const CardGenerator = require('../services/cardGenerator');
const AiModelService = require('../services/aiModelService');
const path = require('path');
const fs = require('fs');

/**
 * @desc    上传文档
 * @route   POST /api/documents/upload
 * @access  私有
 */
const uploadDocument = async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ message: '请上传文件' });
    }

    const { originalname, filename, path: filePath, size } = req.file;
    const fileExtension = path.extname(originalname).toLowerCase().substring(1);
    
    // 解码文件名，确保中文字符正确显示
    const decodedOriginalName = Buffer.from(originalname, 'latin1').toString('utf8');
    
    console.log('上传文件信息:', {
      originalname,
      decodedOriginalName,
      filename,
      filePath,
      size,
      fileExtension
    });
    
    // 创建文档记录
    const document = new Document({
      title: decodedOriginalName.replace(/\.[^/.]+$/, ''), // 移除扩展名
      fileName: decodedOriginalName, // 保存解码后的原始文件名
      fileType: fileExtension,
      filePath,
      fileSize: size,
      uploadedBy: req.user._id,
      processed: false
    });

    await document.save();

    const responseData = {
      message: '文件上传成功',
      document: {
        _id: document._id,
        title: document.title,
        fileName: document.fileName,
        fileType: document.fileType,
        fileSize: document.fileSize,
        createdAt: document.createdAt,
        status: 'UPLOADED'
      }
    };
    
    console.log('上传响应数据:', responseData);
    
    res.status(201).json(responseData);
  } catch (error) {
    console.error('上传文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    处理文档并生成知识卡片
 * @route   POST /api/documents/:id/process
 * @access  私有
 */
const processDocument = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限处理该文档' });
    }

    // 检查是否已处理
    if (document.processed) {
      return res.status(400).json({ message: '文档已经处理过' });
    }

    // 检查是否正在处理中
    if (document.processingStatus === 'processing') {
      return res.status(400).json({ message: '文档正在处理中，请稍后查看结果' });
    }

    // 更新文档状态为处理中
    document.processingStatus = 'processing';
    await document.save();

    // 立即返回响应，表示处理已开始
    res.status(202).json({
      message: '文档处理已开始，请稍后查看结果',
      document: {
        _id: document._id,
        title: document.title,
        processingStatus: document.processingStatus
      }
    });

    // 异步处理文档
    processDocumentAsync(document._id).catch(error => {
      console.error(`处理文档 ${document._id} 时出错:`, error);
    });
  } catch (error) {
    console.error('处理文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * 异步处理文档的辅助函数
 */
const processDocumentAsync = async (documentId) => {
  try {
    console.log(`[processDocumentAsync] 开始处理文档 ${documentId}`);
    
    const document = await Document.findById(documentId);
    if (!document) {
      console.error('找不到要处理的文档:', documentId);
      return;
    }

    // 检查文档是否已经在处理中，以及是否有处理进度
    const isResuming = document.processingStatus === 'failed' && document.processingProgress && document.processingProgress.processedChunks > 0;
    
    if (isResuming) {
      console.log(`[processDocumentAsync] 从失败的地方继续处理文档 ${documentId}，已处理 ${document.processingProgress.processedChunks}/${document.processingProgress.totalChunks} 个块`);
    } else {
      // 重置处理进度
      document.processingProgress = {
        processedChunks: 0,
        totalChunks: 0,
        currentChapter: 0
      };
    }

    // 解析文档（如果是继续处理，则使用已有的内容和结构）
    let content, structure;
    if (!isResuming || !document.content || !document.chapters || document.chapters.length === 0) {
      console.log(`[processDocumentAsync] 开始解析文档 ${documentId}`);
      const parseResult = await DocumentParser.parseDocument(
        document.filePath,
        document.fileType
      );
      content = parseResult.content;
      structure = parseResult.structure;
      console.log(`[processDocumentAsync] 文档解析完成，结构包含 ${structure.length} 个章节`);
      
      // 保存文档内容和结构，以便断点续传
      document.content = content;
      document.chapters = structure;
      await document.save();
    } else {
      console.log(`[processDocumentAsync] 使用已有的文档内容和结构继续处理`);
      content = document.content;
      structure = document.chapters;
    }

    // 更新文档状态为处理中
    document.processingStatus = 'processing';
    await document.save();

    // 生成知识卡片，支持断点续传
    console.log(`[processDocumentAsync] 开始为文档 ${documentId} 生成知识卡片`);
    const cards = await CardGenerator.generateCards(
      content, 
      structure, 
      document._id, 
      document.processingProgress
    );
    console.log(`[processDocumentAsync] 成功为文档 ${documentId} 生成了 ${cards.length} 张卡片`);

    // 检查卡片是否成功保存到数据库
    const savedCardCount = await Card.countDocuments({ sourceDocument: document._id });
    console.log(`[processDocumentAsync] 数据库中文档 ${documentId} 的卡片数量: ${savedCardCount}`);

    // 更新文档状态
    document.processed = true;
    document.processingStatus = 'completed';
    document.cardCount = savedCardCount;
    document.processingProgress = {
      processedChunks: document.processingProgress.totalChunks,
      totalChunks: document.processingProgress.totalChunks,
      currentChapter: structure.length - 1
    };
    await document.save();

    console.log(`文档 ${documentId} 处理完成，生成了 ${savedCardCount} 张卡片`);
  } catch (error) {
    console.error(`异步处理文档 ${documentId} 时出错:`, error);
    
    // 更新文档状态为处理失败，但保留处理进度
    const document = await Document.findById(documentId);
    if (document) {
      document.processingStatus = 'failed';
      document.processingError = error.message || '处理文档时出错';
      await document.save();
    }
  }
};

/**
 * @desc    获取用户的所有文档
 * @route   GET /api/documents
 * @access  私有
 */
const getUserDocuments = async (req, res) => {
  try {
    const documents = await Document.find({ uploadedBy: req.user._id })
      .select('title fileName fileType fileSize processed processingStatus processingError cardCount createdAt')
      .sort({ createdAt: -1 });

    // 格式化文档数据，添加状态字段
    const formattedDocuments = documents.map(doc => ({
      _id: doc._id,
      title: doc.title || '',
      fileName: doc.fileName || '',
      fileType: doc.fileType || '',
      fileSize: doc.fileSize || 0,
      cardCount: doc.cardCount || 0,
      createdAt: doc.createdAt,
      processed: doc.processed,
      processingStatus: doc.processingStatus,
      processingError: doc.processingError,
      // 保留旧的status字段以保持兼容性
      status: doc.processed ? 'PROCESSED' : 'UPLOADED'
    }));

    console.log('返回文档列表个数:', formattedDocuments.length);

    res.json(formattedDocuments);
  } catch (error) {
    console.error('获取用户文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取文档详情
 * @route   GET /api/documents/:id
 * @access  私有
 */
const getDocumentById = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限（只能查看自己上传的文档）
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限查看该文档' });
    }

    // 获取文档关联的卡片数量
    const cardCount = await Card.countDocuments({ sourceDocument: document._id });

    const formattedDocument = {
      _id: document._id,
      title: document.title || '',
      fileName: document.fileName || '',
      fileType: document.fileType || '',
      fileSize: document.fileSize || 0,
      chapters: document.chapters || [],
      cardCount: cardCount || 0,
      createdAt: document.createdAt,
      updatedAt: document.updatedAt,
      processed: document.processed,
      processingStatus: document.processingStatus,
      processingError: document.processingError,
      summary: document.summary || null,
      // 保留旧的status字段以保持兼容性
      status: document.processed ? 'PROCESSED' : 'UPLOADED'
    };

    console.log('返回文档详情:', formattedDocument.fileName);

    res.json(formattedDocument);
  } catch (error) {
    console.error('获取文档详情时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取文档的所有知识卡片
 * @route   GET /api/documents/:id/cards
 * @access  私有
 */
const getDocumentCards = async (req, res) => {
  try {
    const { id } = req.params;
    console.log(`[getDocumentCards] 请求获取文档 ${id} 的卡片`);
    
    const document = await Document.findById(id);

    if (!document) {
      console.log(`[getDocumentCards] 文档 ${id} 不存在`);
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      console.log(`[getDocumentCards] 用户 ${req.user._id} 没有权限查看文档 ${id}`);
      return res.status(403).json({ message: '没有权限查看该文档' });
    }

    console.log(`[getDocumentCards] 查询文档 ${id} 的卡片`);
    
    // 获取文档关联的所有卡片
    const cards = await Card.find({ sourceDocument: document._id })
      .select('title content chapter difficulty tags createdAt')
      .sort({ chapter: 1, createdAt: 1 });

    console.log(`[getDocumentCards] 找到 ${cards.length} 张卡片`);
    
    // 如果没有卡片，检查文档状态
    if (cards.length === 0) {
      console.log(`[getDocumentCards] 文档状态: processed=${document.processed}, processingStatus=${document.processingStatus}`);
    }

    res.json(cards);
  } catch (error) {
    console.error('获取文档卡片时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    更新文档信息
 * @route   PUT /api/documents/:id
 * @access  私有
 */
const updateDocument = async (req, res) => {
  try {
    const { id } = req.params;
    const { title } = req.body;
    
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限修改该文档' });
    }

    // 更新文档信息
    if (title) document.title = title;
    document.updatedAt = Date.now();

    await document.save();

    res.json({
      message: '文档更新成功',
      document: {
        id: document._id,
        title: document.title,
        updatedAt: document.updatedAt
      }
    });
  } catch (error) {
    console.error('更新文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    删除文档
 * @route   DELETE /api/documents/:id
 * @access  私有
 */
const deleteDocument = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限删除该文档' });
    }

    // 删除物理文件
    if (document.filePath && fs.existsSync(document.filePath)) {
      try {
        fs.unlinkSync(document.filePath);
        console.log(`物理文件已删除: ${document.filePath}`);
      } catch (fileError) {
        console.error(`删除物理文件失败: ${document.filePath}`, fileError);
        // 继续删除数据库记录，即使文件删除失败
      }
    }

    // 删除关联的卡片
    await Card.deleteMany({ sourceDocument: document._id });
    
    // 删除关联的学习路径
    const LearningPath = require('../models/LearningPath');
    const UserLearningProgress = require('../models/UserLearningProgress');
    
    // 查找关联的学习路径
    const learningPaths = await LearningPath.find({ documentId: document._id });
    
    // 删除每个学习路径及其关联的用户学习进度
    for (const path of learningPaths) {
      // 删除用户学习进度
      await UserLearningProgress.deleteMany({ learningPathId: path._id });
      // 删除学习路径
      await path.deleteOne();
    }
    
    // 删除文档
    await document.deleteOne();

    res.json({ 
      message: '文档及其关联的卡片和学习路径已成功删除',
      deletedResources: {
        document: 1,
        cards: await Card.countDocuments({ sourceDocument: document._id }),
        learningPaths: learningPaths.length,
        userProgress: await UserLearningProgress.countDocuments({ learningPathId: { $in: learningPaths.map(p => p._id) } })
      }
    });
  } catch (error) {
    console.error('删除文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    获取文档的章节列表
 * @route   GET /api/documents/:id/chapters
 * @access  私有
 */
const getDocumentChapters = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限（只能查看自己上传的文档）
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限查看该文档' });
    }

    // 如果文档有章节信息，返回章节列表
    if (document.chapters && document.chapters.length > 0) {
      return res.json(document.chapters);
    }

    // 如果没有章节信息，返回空数组
    res.json([]);
  } catch (error) {
    console.error('获取文档章节时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    使用通义千问 Qwen-Long 模型生成文档摘要
 * @route   GET /api/documents/:id/summary
 * @access  私有
 */
const generateDocumentSummary = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限处理该文档' });
    }

    // 检查文档是否已处理
    if (!document.processed) {
      return res.status(400).json({ message: '文档尚未处理，请先处理文档' });
    }
    
    // 如果文档已经有摘要，直接返回
    if (document.summary) {
      return res.json({
        summary: document.summary,
        documentId: document._id,
        title: document.title,
        fromCache: true
      });
    }

    // 读取文档内容
    let content = '';
    try {
      if (fs.existsSync(document.filePath)) {
        if (document.fileType.toLowerCase() === 'txt') {
          content = fs.readFileSync(document.filePath, 'utf8');
        } else {
          // 对于非文本文件，我们可以使用已有的解析方法获取内容
          const parsedDoc = await DocumentParser.parseDocument(document.filePath, document.fileType);
          content = parsedDoc.content;
        }
      } else {
        return res.status(404).json({ message: '文档文件不存在' });
      }
    } catch (error) {
      console.error('读取文档内容时出错:', error);
      return res.status(500).json({ message: '读取文档内容时出错' });
    }

    // 利用通义千问的大上下文窗口，但仍然设置合理的限制
    const MAX_CONTENT_LENGTH = 20000; // 增加到20000字符，充分利用模型能力
    const truncatedContent = content.length > MAX_CONTENT_LENGTH ? 
      content.substring(0, MAX_CONTENT_LENGTH) + '...' : content;
    
    console.log(`原始内容长度: ${content.length}, 处理长度: ${truncatedContent.length}`);

    // 使用通义千问 Qwen-Long 模型生成摘要
    try {
      const response = await AiModelService.parseWithQwenLong(truncatedContent, {
        task: 'summarize',
        temperature: 0.3,
        max_tokens: 800  // 增加输出长度以获得更详细的摘要
      });

      if (!response.success) {
        console.error('生成摘要失败:', response.error);
        return res.status(500).json({ message: response.error || '生成摘要失败' });
      }
      
      // 保存摘要到文档
      document.summary = response.result;
      await document.save();
      console.log(`已保存摘要到文档 ${document._id}`);

      res.json({
        summary: response.result,
        documentId: document._id,
        title: document.title,
        fromCache: false
      });
    } catch (error) {
      console.error('生成摘要时出错:', error);
      
      // 提供更具体的错误信息
      let errorMessage = '生成摘要时出错';
      
      if (error.code === 'ECONNABORTED') {
        errorMessage = '请求超时，AI模型处理时间过长';
      } else if (error.response) {
        errorMessage = `AI服务错误(${error.response.status}): ${error.response.data?.message || error.message}`;
      } else if (error.request) {
        errorMessage = '网络连接错误，无法连接到AI服务';
      } else {
        errorMessage = error.message || '生成摘要时出错';
      }
      
      res.status(500).json({ message: errorMessage });
    }
  } catch (error) {
    console.error('生成文档摘要时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

/**
 * @desc    从失败的地方继续处理文档
 * @route   POST /api/documents/:id/reprocess
 * @access  私有
 */
const reprocessDocument = async (req, res) => {
  try {
    const { id } = req.params;
    const document = await Document.findById(id);

    if (!document) {
      return res.status(404).json({ message: '文档不存在' });
    }

    // 检查权限
    if (document.uploadedBy.toString() !== req.user._id.toString()) {
      return res.status(403).json({ message: '没有权限处理该文档' });
    }

    // 检查文档是否处于失败状态
    if (document.processingStatus !== 'failed') {
      return res.status(400).json({ 
        message: '只能重新处理失败的文档',
        currentStatus: document.processingStatus
      });
    }

    // 检查是否有处理进度
    if (!document.processingProgress || document.processingProgress.processedChunks === 0) {
      // 如果没有处理进度，重置文档状态，从头开始处理
      document.processingStatus = 'pending';
      document.processingError = null;
      document.processingProgress = {
        processedChunks: 0,
        totalChunks: 0,
        currentChapter: 0,
        lastProcessedAt: new Date()
      };
    } else {
      // 如果有处理进度，从失败的地方继续处理
      document.processingStatus = 'pending';
      document.processingError = null;
      // 保留现有的处理进度
    }

    await document.save();

    // 立即返回响应，表示处理已开始
    res.status(202).json({
      message: '文档处理已重新开始，将从失败的地方继续',
      document: {
        _id: document._id,
        title: document.title,
        processingStatus: document.processingStatus,
        processingProgress: document.processingProgress
      }
    });

    // 异步处理文档
    processDocumentAsync(document._id).catch(error => {
      console.error(`重新处理文档 ${document._id} 时出错:`, error);
    });
  } catch (error) {
    console.error('重新处理文档时出错:', error);
    res.status(500).json({ message: '服务器错误' });
  }
};

module.exports = {
  uploadDocument,
  processDocument,
  getUserDocuments,
  getDocumentById,
  getDocumentCards,
  updateDocument,
  deleteDocument,
  getDocumentChapters,
  generateDocumentSummary,
  reprocessDocument
}; 